package comp.wxapi.service;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.config.WxPayConfig;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.config.WxMaInMemoryConfig;
import comp.wxapi.bean.BaseConfigBean;
import comp.wxapi.constants.Constants;
import comp.wxapi.utils.ConfigUtils;
import comp.wxapi.vo.WXConfig;

public class MiniappService extends WxAbstractBaseService {
	
	
	
	@Override
	public BaseConfigBean getBaseConfig() {
		printAllHeaders();
		return getBaseConfig(Constants.MINIAPP_KEY, "");
	}

	public BaseConfigBean getBaseConfig(String group) {
		printAllHeaders();
		BaseConfigBean configBean = null;
		if(verifyMinappReferer()) {//小程序环境或者微信调试工具环境调用
			configBean = new BaseConfigBean();
			configBean.setOpenid(getHeader(Constants.HEADER_OPENID));
			configBean.setSessionKey(getHeader("X-Session-SessionKey"));
			String appid = getAppid();
			List<WXConfig> configs = ConfigUtils.getConfigsByAppid(appid);
			setConfigBean(configs, configBean);
		}else {//IDE制作环境调用
			configBean = getBaseConfig(Constants.MINIAPP_KEY, group);
		}
		logger.info("config={}",JSONObject.toJSONString(configBean));
		return configBean;
	}
	
	@Override
	public WxPayConfig getPayConfig(boolean isRefund) {
		printAllHeaders();
		WxPayConfig wxPayConfig = new WxPayConfig();
		List<WXConfig> configs = null;
		if(verifyMinappReferer()) {
			String appid = getAppid();
			configs = ConfigUtils.getConfigsByAppid(appid);
		}else {
			configs = ConfigUtils.getConfigsLikeKey(Constants.MINIAPP_KEY, "");
		}
		logger.info("config={}", JSON.toJSON(configs));
		setWxPayConfig(wxPayConfig, configs, isRefund);
		// 支付通知地址，默认首先通知到组件内部，验签解密等动作成功后才通知到对应的应用
		if (isRefund) {
				wxPayConfig.setNotifyUrl(host() + Constants.MINIAPP_DEFUALT_REFUND_NOFITY_HOST);
		} else {
				wxPayConfig.setNotifyUrl(host() + Constants.MINIAPP_DEFUALT_NOFITY_HOST);
		}
		logger.info("wxPayConfig={}", JSON.toJSON(wxPayConfig));
		return wxPayConfig;
	}
	
	public WxPayConfig getPayConfigByAppid(String appid) {
		printAllHeaders();
		WxPayConfig wxPayConfig = new WxPayConfig();
		List<WXConfig> configs = null;
		configs = ConfigUtils.getConfigsByAppid(appid);
		logger.info("config={}", JSON.toJSON(configs));
		setWxPayConfig(wxPayConfig, configs, true);
		// 支付通知地址，默认首先通知到组件内部，验签解密等动作成功后才通知到对应的应用
		wxPayConfig.setNotifyUrl(host() + Constants.MINIAPP_DEFUALT_REFUND_NOFITY_HOST);
		logger.info("wxPayConfig={}", JSON.toJSON(wxPayConfig));
		return wxPayConfig;
	}


	@Override
	public WxMaService wxMaService(BaseConfigBean baseConfigBean) {
		String appid = baseConfigBean.getAppid();
		WxMaInMemoryConfig wxMaInMemoryConfig = new WxMaInMemoryConfig();
		wxMaInMemoryConfig.setAppid(appid);
		wxMaInMemoryConfig.setSecret(baseConfigBean.getAppsecret());
		wxMaInMemoryConfig.updateAccessToken(getAccessToken(appid, baseConfigBean.getAppsecret()), 7200);
		WxMaService wxMaService = new WxMaServiceImpl();
		wxMaService.setWxMaConfig(wxMaInMemoryConfig);
		return wxMaService;
	}
	
	/**
	 * 从小程序的请求Referer信息获取请求的小程序Appid
	 * @return
	 */
	public String getAppid() {
		String referer = getHeader("Referer");
		referer = referer.substring(26, referer.length());
		referer = referer.split("/")[0];
		return referer;
	}
	
	public boolean verifyMiniappReferrer(String appid) {
		String regEx = "^https://servicewechat.com/"+appid+"/(\\d+(\\.\\d+)?|devtools)/page-frame.html$";
		String referer = getHeader("Referer");
		Pattern pattern = Pattern.compile(regEx);  
	    Matcher matcher = pattern.matcher(referer); 
	    return matcher.matches();
	}
	
	public boolean verifyMinappReferer() {
		String regEx = "^https://servicewechat.com/(.*)/(\\d+(\\.\\d+)?|devtools)/page-frame.html$";
		String referer = getHeader("Referer");
		Pattern pattern = Pattern.compile(regEx);  
	    Matcher matcher = pattern.matcher(referer); 
	    return matcher.matches();
	}

}
